use super::module_name;
use crate::config::remote_config;
use mongo_util;
use mongo_util::OptionError;
use mongodb::{Client, Database};
use remote_log_util;
use std::sync::RwLock;

lazy_static::lazy_static! {
    static ref MONGO_DB_OBJ:  RwLock<Option<MongoDbConnection>>=RwLock::new(None);
}

struct MongoDbConnection {
    #[allow(unused)]
    client: Client,
    db: Database,
}

/// 获取mongo数据库对象
pub fn mongo_db() -> Database {
    MONGO_DB_OBJ.read().unwrap().as_ref().unwrap().db.clone()
}

pub(super) async fn init_mongo_db() {
    // 读取配置
    let conn = remote_config::get_common_config().mongo_connection.clone();

    // 初始化数据库连接
    {
        let db_result = MongoDbConnection::new(conn).await;
        match db_result {
            Ok(val) => {
                *MONGO_DB_OBJ.write().unwrap() = Some(val);
            }
            Err(err) => {
                remote_log_util::remote_error!(
                    module_name(),
                    format!("connect to mongodb error:{:?}", &err)
                )
                .await;
                panic!("{}", err)
            }
        }
    }
}

impl MongoDbConnection {
    /// 创建连接
    pub async fn new(conn: String) -> Result<Self, OptionError> {
        let client_option = mongo_util::ClientOptions::parse(conn.as_str()).await?;
        let client = Client::with_options(client_option.origin_options())
            .map_err(|err| OptionError::MongoError(err))?;
        let db = client.database(client_option.db_name().as_str());

        Ok(MongoDbConnection { client, db })
    }
}
